package run.bottle.common.mvc;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import run.bottle.common.entity.mvc.RestResponse;
import run.bottle.common.exception.AbstractBottleException;

import javax.servlet.http.HttpServletRequest;

/**
 * @author liyc
 * @date 2022-05-06
 */
@RestControllerAdvice
public class ControllerExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class);

    @ExceptionHandler(AbstractBottleException.class)
    public ResponseEntity<RestResponse> commonExceptionHandler(AbstractBottleException e, HttpServletRequest request) {
        logger.error("current uri=[{}]", request.getRequestURI());
        RestResponse restResponse = handleBaseException(e);
        restResponse.setStatus(e.getStatus().value());
        restResponse.setResult(e.getErrorData());
        return new ResponseEntity<>(restResponse, e.getStatus());
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestResponse handleGlobalException(Exception e) {
        RestResponse baseResponse = handleBaseException(e);
        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
        baseResponse.setStatus(status.value());
        baseResponse.setMessage(status.getReasonPhrase());
        return baseResponse;
    }

    private <T> RestResponse handleBaseException(Throwable t) {
        Assert.notNull(t, "Throwable must not be null");

        RestResponse restResponse = RestResponse.error();
        restResponse.setMessage(t.getMessage());

        logger.error("Captured an exception:", t);

        return restResponse;
    }


}
